/** @jsxImportSource @emotion/react */
import {jsx, SerializedStyles} from "@emotion/react";
import * as React from "react";
import { Text } from "./Text";
// import PropTypes from "prop-types";
import { MenuLabel } from "./Menu";
import { useTheme } from "./Theme/Providers";
import { noOp } from "./misc/noop";
import { safeBind } from "./Hooks/compose-bind";
// import {ElementType} from "react";
import { OnPressFunction, usePressable } from "./Hooks/pressable-hook";




export interface ListProps extends React.HTMLAttributes<HTMLDivElement> {
    /** A series of ListItem elements */
    children?: React.ReactNode;
}

export const List = (
    {
     children,
     ...other
 }:ListProps) => {
    return <nav {...other}>{children}</nav>;
};

// List.propTypes = {
//     children: PropTypes.node
// };

interface ListItemProps extends React.HTMLAttributes<any> {
    onPress?: OnPressFunction;
    /**主体标签 =div */
    component?: React.ElementType<any>;

    /** An icon or avatar to appear to the left of the text content
     * 应该安排视觉宽度很小的内容。 会在垂直高度方向上居中显示；
     *  */
    contentBefore?: React.ReactNode;
    /** an icon to appear to the right of the text content
     * 应该安排视觉宽度很小的内容。 会在垂直高度方向上居中显示；
     * */
    contentAfter?: React.ReactNode;

    /** whether the list item is interactive (ie., can be clicked as a button) */
    interactive?: boolean;
    /** optional third row of content
     * 更多内容： 可选的  扩展第三行的。
     * */
    children?: React.ReactNode;
    /** whether primary and secondary text should be wrapped */
    wrap?: boolean;
    /** The primary text content of the list item
     * 第一行 主要内容
     * */
    primary: string | React.ReactNode;
    /** the secondary text content
     * 第二行 可选的 内容。
     * */
    secondary?: string | React.ReactNode;
    noBind?:boolean;  //防止Can't perform a React state update on an unmounted component
    terminateOnScroll?: boolean;
    delay?: number;
    //对第二行secondary整行的控制
    secondStyle?: SerializedStyles;
    [key: string]: any; // back hack to permit things like to='/page'
}
/**准备替换掉旧的 ListItem, #简易版本。没有用旧的"react-gesture-responder"包！
 * [考虑] 没必要提供拉拽的同时取消当前点击到的ListItem避免触发。 而触摸屏本就没这样问题。
 * 列表底下的各个项目：可以插入大类分类层次 ListSection。
 *    <ListSection >
 <ListItem  />
 </ListSection>
 <Divider muted />
 若通过<ListItemcss={{padding: "0.3rem 0.3rem",}}的，在这里实际由...other接受了外部样式注入修改。
 [准备移除 ] useTouchable ？
 #问题：轮播台电脑模式拉动触发，同时触发点击。旧版本:会存在等待进一步Move消息可能会取消的步骤。
 * */
export const ListItem = ({
                             primary,
                             secondary,
                             contentBefore,
                             interactive = true,
                             children,
                             wrap = true,
                             contentAfter,
                             onPress = noOp,
                             component: Component = "div",
                             noBind=false,
                             terminateOnScroll = false,
                             delay=30,
                             secondStyle,
                             ...other
                         }:ListItemProps) => {
    const interactiveProps = interactive
        ? {
            role: "button",
            tabIndex: 0
        }
        : {};
    const isLink = other.to || other.href;
    //这个{bind｛ref｝}给了哪一个Div;那么就针对哪一个DIV的矩形框框才能触发函数 onPress()。从z-index维度上看上一层的更小的div优先。
    const { bind, hover, active } = usePressable({
        onPress,
        behavior: isLink ? "link" : "button"
    });
    const theme = useTheme();
    //console.log("ListItemdl=",delay, "terminateOnScroll=",terminateOnScroll);

    return (
        <Component
            className="ListItem"
            css={[
                {
                    display: "block",
                    textDecoration: "none",
                    outline: "none",
                    padding: theme.spaces.sm,
                    background: "transparent",
                    WebkitTapHighlightColor: "transparent",
                    transition: "background 0.07s ease",
                    [theme.mediaQueries.lg]: {
                        paddingLeft: theme.spaces.lg,
                        paddingRight: theme.spaces.lg
                    },
                    ":last-child": {
                        borderBottom: "none"
                    },
                    "@media print": {
                        transition: 'unset',
                    },
                },

            ]}

            {...other}
        >
            <div
                className="ListItem__container"
                css={{ display: "flex", alignItems: "center" }}
            >
                {contentBefore && (
                    <div
                        className="ListItem__content-before"
                        css={{ marginRight: theme.spaces.md }}
                    >
                        {contentBefore}
                    </div>
                )}

                <div
                    className="ListItem__content"
                    css={[
                        {
                            flex: 1,
                            overflow: "hidden",
                        },
                        interactive && {
                            cursor: "pointer",
                            ":focus": {
                                boxShadow: `inset 0 0 3px ${theme.colors.text.selected}`
                            },
                            ":focus:not([data-focus-visible-added])": {
                                boxShadow: "none"
                            }
                        },
                        interactive &&
                        hover && {
                            background: theme.colors.background.tint1
                        },
                        interactive &&
                        active && {
                            background: theme.colors.background.tint2
                        }
                    ]}
                    {...interactiveProps}
                    {...safeBind(!noBind&&interactive ? bind : {}) }
                >
                    <Text
                        className="ListItem__primary"
                        wrap={wrap}
                        variant="body"
                        css={{ display: "block", fontWeight: 500 }}
                    >
                        {primary}
                    </Text>
                    {secondary && (
                        <Text
                            className="ListItem__secondary"
                            wrap={wrap}
                            css={[
                                {
                                    display: "block",
                                    fontSize: theme.fontSizes[0],
                                },
                                secondStyle
                            ]}
                            variant="body"
                            muted
                        >
                            {secondary}
                        </Text>
                    )}
                    {children}
                </div>
                {contentAfter && (
                    <div
                        className="ListItem__content-after"
                        css={{ flex: "0 0 auto" }}
                    >
                        {contentAfter}
                    </div>
                )}
            </div>
        </Component>
    );
};


interface ListSectionProps extends React.HTMLAttributes<HTMLDivElement> {
    /** A title of the section */
    title: string;
    children?: React.ReactNode;
    /** whether the title should stick to the top of the scrollable content */
    sticky?: boolean;
}

export const ListSection = ({
                                                                           title,
                                                                           children,
                                                                           sticky = true,
                                                                           ...other
                                                                       }:ListSectionProps) => {
    const theme = useTheme();
    const bg = theme.colors.background.layer;
    return (
        <div
            css={{
                ":first-child > *": {
                    borderTop: "none"
                }
            }}
        >
            <MenuLabel
                css={{
                    position: sticky ? "sticky" : "static",
                    top: 0,
                    backgroundColor: sticky ? bg : "transparent",
                    padding: theme.spaces.sm,
                    paddingLeft: theme.spaces.md,
                    marginTop: theme.spaces.md,
                    [theme.mediaQueries.lg]: {
                        paddingLeft: theme.spaces.lg,
                        paddingRight: theme.spaces.lg
                    }
                }}
                {...other}
            >
                {title}
            </MenuLabel>
            {children}
        </div>
    );
};

// ListSection.propTypes = {
//     title: PropTypes.string.isRequired,
//     sticky: PropTypes.bool,
//     children: PropTypes.node
// };


interface ListFlexRowProps extends React.HTMLAttributes<any> {
    onPress?: OnPressFunction;
    /**主体标签 默认=div
     * ElementType<any> 是任意标签或组件。 component={"li"} component={RouterLink} 组件儿子嵌套法的。
     * 很多w3c标签能用但样式有些变动，但是 "select" "svg" 不能用。
     *  */
    component?: React.ElementType<any>;

    /** 前面 在水平方向并排
     *  */
    contentBefore?: React.ReactNode;
    /** 后面 在水平方向并排
     * */
    contentAfter?: React.ReactNode;

    /** whether the list item is interactive (ie., can be clicked as a button) */
    interactive?: boolean;
    /** 更多内容。
     * primary secondary +children: 三个部分实际布局不做区分。
     * */
    children?: React.ReactNode;
    /** whether primary and secondary text should be wrapped */
    wrap?: boolean;
    /** The primary text content of the list item
     *  主要内容，样式不同
     * */
    primary?: string | React.ReactNode;
    /** the secondary text content
     *  附加内容，样式不同
     * */
    secondary?: string | React.ReactNode;
    noBind?:boolean;  //防止Can't perform a React state update on an unmounted component
    terminateOnScroll?: boolean;
    delay?: number;
    //对第二行secondary整行的控制
    secondStyle?: SerializedStyles;
    [key: string]: any; // back hack to permit things like to='/page'
}

/**代替ListItem,实现更为自由样式, 类比Table组件的每一行TableRow功能。
 <ListFlexRow css={{
        padding: "0.3rem 0.3rem",
        alignItems: "center",
        display: "flex",
        justifyContent: "space-between",
        "& em": {
        fontStyle: "normal",
            color: theme.colors.text.selected
        },
        "& > *": {
            flex: 1,
                overflow: "hidden"
        }
    }}
 > </ListFlexRow>
 若通过<ListFlexRow css={{padding: "0.3rem 0.3rem",}}的，在这里实际由...other接受了外部样式注入修改。
 * */
export const ListFlexRow = ({
                                primary,
                                secondary,
                                contentBefore,
                                interactive = true,
                                children,
                                wrap = true,
                                contentAfter,
                                onPress = noOp,
                                component: Component = "div",
                                noBind=false,
                                terminateOnScroll = false,
                                delay=30,
                                secondStyle,
                                ...other
                            }:ListFlexRowProps) => {
    const interactiveProps = interactive
        ? {
            role: "button",
            tabIndex: 0
        }
        : {};
    const isLink = other.to || other.href;
    const { bind, hover, active } = usePressable({
        onPress,
        behavior: isLink ? "link" : "button"
    });
    const theme = useTheme();

    return (
        <Component
            className="ListFlexRow"
            css={[
                {
                    display: 'flex',
                    flexDirection: 'row',
                    alignContent: 'center',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                    flexWrap: 'nowrap',
                    textDecoration: "none",
                    outline: "none",
                    padding: "0.15rem 0.2rem",
                    background: "transparent",
                    WebkitTapHighlightColor: "transparent",
                    transition: "background 0.07s ease",
                    [theme.mediaQueries.md]: {
                        padding: `0.15rem 0.4rem`,
                    },
                    [theme.mediaQueries.xl]: {
                        padding: `${theme.spaces.xs} 1rem`,
                    },
                    ":last-child": {
                        borderBottom: "none"
                    },
                    "@media print": {
                        transition: 'unset',
                    },
                },
                interactive && {
                    cursor: "pointer",
                    ":focus": {
                        boxShadow: `inset 0 0 3px ${theme.colors.text.selected}`
                    },
                    ":focus:not([data-focus-visible-added])": {
                        boxShadow: "none"
                    }
                },
                interactive &&
                hover && {
                    background: theme.colors.background.tint1
                },
                interactive &&
                active && {
                    background: theme.colors.background.tint2
                }
            ]}
            {...interactiveProps}
            {...safeBind(!noBind&&interactive ? bind : {}, other)}
        >
            {contentBefore && (
                <div
                    className="ListFlexRow-before"
                    css={{ marginRight: theme.spaces.md }}
                >
                    {contentBefore}
                </div>
            )}

            <div className="ListFlexRow_content"
                 css={{
                     display: 'flex',
                     flexDirection: 'row',
                     alignContent: 'center',
                     justifyContent: 'space-between',
                     alignItems: 'center',
                     flexWrap: 'wrap',
                     flex: 1,
                 }}
            >
                {primary && (
                    <Text
                        className="ListFlexRow_primary"
                        wrap={wrap}
                        variant="body"
                        css={{ fontWeight: 500 }}
                    >
                        {primary}
                    </Text>
                )}
                {secondary && (
                    <Text
                        className="ListFlexRow_secondary"
                        wrap={wrap}
                        css={[
                            {
                                fontSize: theme.fontSizes[0],
                            },
                            secondStyle
                        ]}
                        variant="body"
                        muted
                    >
                        {secondary}
                    </Text>
                )}

                {children}
            </div>

            {contentAfter && (
                <div
                    className="ListFlexRow-after"
                    css={{ flex: "0 0 auto" }}
                >
                    {contentAfter}
                </div>
            )}
        </Component>
    );
};
